#include "adc.h"
#include "timer.h"

#define ADC_DR_Address ((uint32_t)ADC + ADC_Sequence_0)

void AdcConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_ODrv = GPIO_ODrv_NORMAL;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOD, GPIO_Pin_10, PD10_AN24);
	
	
	DMA_InitTypeDef InitCfg;
	/* Enable DMA clock */
	RCC_AHBPeriphClockOnOff(RCC_AHB_DMA, SH_ON);
	InitCfg.Enable = SH_DISABLE;
	InitCfg.TransCompleteIE = SH_DISABLE;
	InitCfg.HalfCompleteIE = SH_DISABLE;
	InitCfg.BurstCompleteIE = SH_DISABLE;
	InitCfg.TransErrorIE = SH_DISABLE;
	
	InitCfg.DestAddrType = DMA_ADDR_INC;		/*!< Destination address mode: DMA_ADDR_INC,DMA_ADDR_DEC,DMA_ADDR_FIXED,DMA_ADDR_LOOP */
	InitCfg.SourceAddrType = DMA_ADDR_FIXED;	/*!< Source address mode: DMA_ADDR_INC,DMA_ADDR_DEC,DMA_ADDR_FIXED,DMA_ADDR_LOOP */
	InitCfg.DestUnitSize = DMA_UNIT_HALFWORD;   /*!< Destination unit size: DMA_UNIT_BYTE,DMA_UNIT_HALFWORD,DMA_UNIT_WORD */
	InitCfg.SourceUnitSize = DMA_UNIT_HALFWORD; /*!< Source unit size: DMA_UNIT_BYTE,DMA_UNIT_HALFWORD,DMA_UNIT_WORD */
	InitCfg.Priority = DMA_PRIOR_MIDDLE;		/*!< DMA's priority : DMA_PRIOR_LOW, DMA_PRIOR_MIDDLE, DMA_PRIOR_HIGH,DMA_PRIOR_HIGHEST*/
	InitCfg.OneBurstLen = BURST_LEN_1UNIT;		/*!< One burst transmit length: @ref DMA_BURSTLEN_Type*/
	InitCfg.StreamSelect = STRMSEL_CH2_ADC;   /*!< DMA stream contrl source select */
	InitCfg.TriggerMode = DMA_TRGMODE_ONESHOT;  /*!< DMA tragle mode : DMA_TRGMODE_ONESHOT,DMA_TRGMODE_TOEND*/
	//InitCfg.rev1              : 8;             /*!< reserved */
	InitCfg.Reload = SH_ENABLE;				/*!< autoreload ChannelNO's settings */
	InitCfg.BurstIdle = BURST_IDLE_32CYCLE; /*!< set burst idle cycles BURST_IDLE_1CYCLE ~ BURST_IDLE_32CYCLE*/
//	InitCfg.BurstCount = 4;					/*NPKT !< Burst Count to transmit value(0~0x1FF) means (1~0x200) burst count*/

	InitCfg.SourceAddr = ADC_DR_Address;			  //move data form addr:0x00000200 in flash to addr:0x10000200 in ram
//	InitCfg.DestAddr = (uint32_t)&ADC_ConvertedValue; //number of datas: (NPKT+1) * DestUnitSize * (OneBurstLen)  3*1*3=9BYTES
													  //after transmissioning 9BYTES ,entry DMA interrupt
	DMA_Init(DMA_CH_NO_2, &InitCfg);
	DMA_OnOff(DMA_CH_NO_2, SH_OFF); /*!< Enable DMA after assignment*/
	

	
	ADC_InitTypeDef ADC_InitStructure;

	/* ADC1 configuration */
	ADC_StructInit(&ADC_InitStructure);
	/* Enable ADC clock */
	RCC_APB0PeriphClockOnOff(RCC_APB0_ADC, SH_ON);

	GPIO_PinAFConfig(GPIOD, GPIO_Pin_10, PD10_AN24);

	ADC_InitStructure.ADC_ConversionMode = ADC_ConversionMode_Continuous;
	ADC_InitStructure.ADC_NumOfConversion = ADC_NumOfConversion_1;
	ADC_InitStructure.ADC_Prescaler = ADC_Prescaler_1;
	ADC_InitStructure.ADC_RefVoltage = ADC_RefVoltage_AVDD;
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12Bit;
	ADC_InitStructure.ADC_SampleTime = ADC_SampleTime_15Cycles;
	ADC_InitStructure.ADC_SequencePointer = ADC_Sequence_0;
	ADC_InitStructure.ADC_Trigger = ADC_Trigger_Software; //ADC_Trigger_MCM2TRG1;
	ADC_InitStructure.ADC_TwoSampleGap = ADC_TwoSampleGap_4Cycles;
	ADC_Init(ADC, &ADC_InitStructure);

	ADC_ChannelConfig(ADC, ADC_Channel_24, ADC_Sequence_0, ADC_TwoSampleGap_Enable);

	ADC_OnOff(ADC, SH_ON); //Power on ADC module

	ADC_SoftwareStartConversion(ADC);

	/* ADC conversion is complete, triggering DMA enable */
//	ADC_TriggerDMAEnable(SH_ENABLE);
	
}

int ADC_GetValue(uint16_t *buff, uint16_t size)
{
	uint32_t Timeout = 200;
	uint32_t tickstart = 0;
	DMA_CH_TypeDef *pDMAChannel;
	pDMAChannel = DMA_CHx(DMA_CH_NO_2);
	pDMAChannel->DAR = (uint32_t)buff;
	
	DMA_SetDataCounter(DMA_CH_NO_2,size-1);
	
	DMA_OnOff(DMA_CH_NO_2, SH_ON);
	ADC_TriggerDMAEnable(SH_ENABLE);
	
	tickstart = HAL_GetTick();
	while(DMA_IsComplete(DMA_CH_NO_2) == SH_FALSE)
	{
		IWDT->CLR = 0xAAAA;
		if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
		{
			DMA_ClearFlag(DMA_CH_NO_2,DMA_TRANS_COMPLETE); 
			return -1;
		}
	}
	DMA_ClearFlag(DMA_CH_NO_2,DMA_TRANS_COMPLETE); 
	
	
	DMA_OnOff(DMA_CH_NO_2, SH_OFF);
	return 0;
}




